package com.lms.resource.service.config;

import com.lms.resource.service.extension.LmsAuthenticationEntryPoint;
import com.lms.resource.service.extension.LmsBearerTokenResolver;
import com.lms.resource.service.handler.PermissionHandler;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableMethodSecurity
@RequiredArgsConstructor
public class ResourceServerConfiguration {
    private final RedisTemplate<String, Object> redisTemplate;
    private final HttpSecurity http;

    @Bean
    public SecurityFilterChain filterChain() throws Exception {
        http
                .authorizeHttpRequests(authorize -> authorize
                        .requestMatchers("/actuator/**", "/v3/api-docs/**", "/swagger-ui/**",
                                "/swagger-ui.html", "/doc.html").permitAll()
                        .anyRequest().authenticated()
                )
                .oauth2ResourceServer(oauth2 -> oauth2
                        .bearerTokenResolver(new LmsBearerTokenResolver(redisTemplate))
                        .authenticationEntryPoint(lmsAuthenticationEntryPoint())
                        .jwt(jwtConfigurer -> {}));
        return http.build();
    }

    @Bean
    public JwtAuthenticationConverter jwtAuthenticationConverter() {
        JwtGrantedAuthoritiesConverter grantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
        grantedAuthoritiesConverter.setAuthorityPrefix("");
        grantedAuthoritiesConverter.setAuthoritiesClaimName("authorities");

        JwtAuthenticationConverter jwtAuthenticationConverter = new JwtAuthenticationConverter();
        jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(grantedAuthoritiesConverter);
        return jwtAuthenticationConverter;
    }

    @Bean
    public LmsAuthenticationEntryPoint lmsAuthenticationEntryPoint() {
        return new LmsAuthenticationEntryPoint();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return PasswordEncoderFactories.createDelegatingPasswordEncoder();
    }

    @Bean("pms")
    public PermissionHandler permissionHandler() {
        return new PermissionHandler();
    }

    public static void main(String[] args) {
        String encode = PasswordEncoderFactories.createDelegatingPasswordEncoder().encode("123");
        System.out.println(encode);
    }
}
